#pragma once
#include "rendertech.h"
#include <string>
class CRenderEMCubeMap :
	public RenderTech
{
public:
	CRenderEMCubeMap();
	virtual ~CRenderEMCubeMap(void);

	//D3D series functions
	virtual HRESULT OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, CDirectoryUtil* pDirUtil, void* pUserContext);
	virtual HRESULT OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain,
		const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, CDirectoryUtil* pDirUtil, void* pUserContext );
	virtual void OnD3D11ReleasingSwapChain( void* pUserContext );
	virtual void OnD3D11DestroyDevice( void* pUserContext );
	virtual void OnD3D11FrameRender( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext, CBaseCamera* pViewCamera, CDirectoryUtil* pDirUtil, double fTime,
		float fElapsedTime, void* pUserContext );
	virtual void InitEffectsVariables();
	virtual void ReloadEffectsDebug(ID3D11Device* pd3dDevice, CDirectoryUtil* pDirUtil);
	
	HRESULT ComputeSHCoeffsEM(CDirectoryUtil* pDirUtil);
	float* GetSHData( int nChannel )
	{
		if( nChannel < 0 || nChannel > 3 ) return NULL;
		else
			return m_fSHData[nChannel];
	};
	inline unsigned int GetOrderNum(){return m_iSHOrder;};

	ID3D11Texture2D* GetD3D10EnvironmentMap()
	{
		return m_pEnvironmentMap;
	}
	ID3D11ShaderResourceView* GetD3D10EnvironmentMapRV()
	{
		return m_pEnvironmentRV;
	}
	void    SetD3D11EnvironmentMap( ID3D11Texture2D* pCubeTexture )
	{
		m_pEnvironmentMap = pCubeTexture;
	}
	

	HRESULT ChangeEMFile(TCHAR* strEMFileName, ID3D11Device* pd3dDevice, CDirectoryUtil* pDirUtil);
	HRESULT SetEMFileName(TCHAR* strEMFileName)
	{
		if(!strEMFileName)
			return E_FAIL;
		m_EMFileName.clear();
		m_EMFileName.assign(strEMFileName);
		printf("WARNING!: Only EM Filename is assigned, and no textured created yet!!!\n");
		return S_OK;
	}
	
protected:
	ID3D11Texture2D* m_pEnvironmentMap;
	ID3D11ShaderResourceView* m_pEnvironmentRV;
	ID3D11InputLayout* m_pVertexLayout;
	ID3D11Buffer* m_pVB;
	std::wstring m_EMFileName;

	//SH
	float   m_fSHData[3][D3DXSH_MAXORDER*D3DXSH_MAXORDER];
	unsigned int m_iSHOrder;


	//effects variable
	ID3DX11EffectTechnique* m_pRenderTech;
	ID3DX11EffectMatrixVariable* m_pmInvWorldViewProj;
	ID3DX11EffectShaderResourceVariable* m_pCubeMapSR;
	ID3DX11EffectScalarVariable* m_pfExpo;
	ID3DX11EffectScalarVariable* m_pfGamma;
};



//-----------------------------------------------------------------------------
struct SHCubeProj
{
	float* pRed,*pGreen,*pBlue;
	int iOrderUse; // order to use
	float   fConvCoeffs[6]; // convolution coefficients

	void    InitDiffCubeMap( float* pR, float* pG, float* pB )
	{
		pRed = pR;
		pGreen = pG;
		pBlue = pB;

		iOrderUse = 3; // go to 5 is a bit more accurate...
		fConvCoeffs[0] = 1.0f;
		fConvCoeffs[1] = 2.0f / 3.0f;
		fConvCoeffs[2] = 1.0f / 4.0f;
		fConvCoeffs[3] = fConvCoeffs[5] = 0.0f;
		fConvCoeffs[4] = -6.0f / 144.0f; // 
	}

	void    Init( float* pR, float* pG, float* pB )
	{
		pRed = pR;
		pGreen = pG;
		pBlue = pB;

		iOrderUse = 6;
		for( int i = 0; i < 6; i++ ) fConvCoeffs[i] = 1.0f;
	}
};
